﻿using System;
using System.Collections.Generic;
using System.ServiceModel;
using BusinessLogicLibrary;
using entities;

namespace ServiceLibrary
{
    [ServiceBehavior(IncludeExceptionDetailInFaults = true)]
    public class InternalService : IInternalService
    {
        private readonly BookingModule _booking;
        private readonly CheckInModule _checkin;
        private readonly CheckoutModule _chekout;
        private readonly CustomerModule _customer;
        private readonly RoomModule _room;
        private readonly SearchModule _search;
        private readonly SupplyModule _supply;

        public InternalService()
        {
            _booking = new BookingModule();
            _customer = new CustomerModule();
            _room = new RoomModule();
            _search = new SearchModule();
            _checkin = new CheckInModule();
            _chekout = new CheckoutModule();
            _supply = new SupplyModule();
        }

        #region"CUSTOMER Management"

        public bool CustomerAdd(string pIdentityNumber, string pCustomerName, string pCustomerPhone,
                                string pCustomerEmail, bool pCustomerSex, out string account)
        {
            try
            {
                return _customer.CreateCustomer(pIdentityNumber, pCustomerName, pCustomerPhone, pCustomerEmail,
                                                pCustomerSex, out account);
            }
            catch (Exception ex)
            {
                throw new FaultException(ex.Message);
            }
        }

        public bool CustomerModify(int pId, string pIdentityNumber, string pCustomerName, string pCustomerPhone,
                                   string pCustomerEmail, bool pCustomerSex)
        {
            try
            {
                return _customer.ModifyCustomer(pId, pIdentityNumber, pCustomerName, pCustomerPhone, pCustomerEmail,
                                                pCustomerSex);
            }
            catch (Exception ex)
            {
                throw new FaultException(ex.Message);
            }
        }

        public List<Customer> CustomersGet(string customerName, string customerEmail, string customerAccount)
        {
            try
            {
                return _customer.GetCustomers(customerName, customerEmail, customerAccount);
            }
            catch (Exception ex)
            {
                throw new FaultException(ex.Message);
            }
        }

        public Customer CustomerGet(int customerId)
        {
            try
            {
                return _customer.GetCustomer(customerId);
            }
            catch (Exception ex)
            {
                throw new FaultException(ex.Message);
            }
        }

        public Customer CustomerGetByAccount(string account)
        {
            try
            {
                return _customer.GetCustomerByAccount(account);
            }
            catch (Exception ex)
            {
                throw new FaultException(ex.Message);
            }
        }

        public Customer CustomerGetByEmail(string email)
        {
            try
            {
                return _customer.GetCustomerByEmail(email);
            }
            catch (Exception ex)
            {
                throw new FaultException(ex.Message);
            }
        }


        public bool CustomerEmailCheck(string email)
        {
            try
            {
                return _customer.CheckCustomerEmail(email);
            }
            catch (Exception ex)
            {
                throw new FaultException(ex.Message);
            }
        }

        public bool CustomerAccountCheck(string id)
        {
            try
            {
                return _customer.CheckCustomerAccount(id);
            }
            catch (Exception ex)
            {
                throw new FaultException(ex.Message);
            }
        }

        #endregion

        #region "SEARCH Room for Booking"

        public List<vRoomInfo> RoomsSearch(DateTime inDate, DateTime outDate, int roomTypeId, int minPrice, int maxPrice,
                                           bool view, bool bath, bool balcony)
        {
            try
            {
                return _search.SearchRooms(inDate, outDate, roomTypeId, minPrice, maxPrice, view, bath, balcony);
            }
            catch (Exception ex)
            {
                throw new FaultException(ex.Message);
            }
        }

        #endregion

        #region "Booking Management"

        public bool BookingRemove(int bookingId)
        {
            try
            {
                return _booking.DeleteBooking(bookingId);
            }
            catch (Exception ex)
            {
                throw new FaultException(ex.Message);
            }
        }

        public List<Booking> BookingsGetByCustomerId(int customerId)
        {
            try
            {
                return _booking.GetBookingByCustomerId(customerId);
            }
            catch (Exception ex)
            {
                throw new FaultException(ex.Message);
            }
        }

        public bool BookingAdd(int customerId, List<int> roomId, DateTime checkInDate, DateTime checkOutDate,
                               string employeeAccount, string employeePassword)
        {
            try
            {
                return _booking.CreateBooking(customerId, roomId, checkInDate, checkOutDate, employeeAccount,
                                              employeePassword);
            }
            catch (Exception ex)
            {
                throw new FaultException(ex.Message);
            }
        }

        public Booking BookingGet(int bookingId)
        {
            try
            {
                return _booking.GetBooking(bookingId);
            }
            catch (Exception ex)
            {
                throw new FaultException(ex.Message);
            }
        }

        #endregion

        #region "ROOM Management"

        public List<RoomType> RoomTypesGet()
        {
            try
            {
                return _room.GetRoomTypes();
            }
            catch (Exception ex)
            {
                throw new FaultException(ex.Message);
            }
        }

        #endregion

        #region "CHECKIN Management"

        public bool CheckInRemove(int checkinId)
        {
            try
            {
                return _checkin.RemoveCheckIn(checkinId);
            }
            catch (Exception ex)
            {
                throw new FaultException(ex.Message);
            }
        }

        public CheckIn CheckInGetById(int checkinId)
        {
            try
            {
                return _checkin.GetCheckIn(checkinId);
            }
            catch (Exception ex)
            {
                throw new FaultException(ex.Message);
            }
        }


        public List<CheckIn> CheckInsIncome()
        {
            try
            {
                return _checkin.CheckInsIncome();
            }
            catch (Exception ex)
            {
                throw new FaultException(ex.Message);
            }
        }

        public bool CheckinLock(List<int> checkinIds)
        {
            try
            {
                return _checkin.LockCheckin(checkinIds);
            }
            catch (Exception ex)
            {
                throw new FaultException(ex.Message);
            }
        }

        public List<CheckIn> CheckInsGetByBookingId(int bookingId)
        {
            try
            {
                return _checkin.GetCheckInsByBookingId(bookingId);
            }
            catch (Exception ex)
            {
                throw new FaultException(ex.Message);
            }
        }

        public List<CheckIn> CheckInsGetByCustomerId(int customerId)
        {
            try
            {
                return _checkin.GetCheckInsByCustomerId(customerId);
            }
            catch (Exception ex)
            {
                throw new FaultException(ex.Message);
            }
        }

        public List<vSupplyOrder> SupplyOrdersGet(int checkinId)
        {
            try
            {
                return _checkin.GetSupplyOrders(checkinId);
            }
            catch (Exception ex)
            {
                throw new FaultException(ex.Message);
            }
        }

        public bool CheckinsAccept(int checkinId, string employeeAccount, string employeePassword, string guestInfo)
        {
            try
            {
                return _checkin.AcceptCheckins(checkinId, employeeAccount, employeePassword, guestInfo);
            }
            catch (Exception ex)
            {
                throw new FaultException(ex.Message);
            }
        }

        public bool CheckinModify(int checkinId, string guestInfo)
        {
            try
            {
                return _checkin.ModifyCheckin(checkinId, guestInfo);
            }
            catch (Exception ex)
            {
                throw new FaultException(ex.Message);
            }
        }

        #endregion

        #region "CHECKOUT Management"
    
        public List<vBill> BillGetByCheckins(List<int> checkinId)
        {
            try
            {
                return _chekout.GetBill(checkinId);
            }
            catch (Exception ex)
            {
                throw new FaultException(ex.Message);
            }
        }

        public List<vBill> CheckOutByCheckins(List<int> checkinId, string employeeAccount, string employeePassword)
        {
            try
            {
                return _chekout.CheckOut(checkinId, employeeAccount, employeePassword);
            }
            catch (Exception ex)
            {
                throw new FaultException(ex.Message);
            }
        }

        #endregion

        #region "SUPPLY"

        public List<SupplyDetail> SupplyDetailsGet()
        {
            try
            {
                return _supply.GetSupplyDetails(true);
            }
            catch (Exception ex)
            {
                throw new FaultException(ex.Message);
            }
        }

        public List<Supply> SuppliesGetByCheckinId(int checkinId)
        {
            try
            {
                return _supply.GetSupplies(checkinId);
            }
            catch (Exception ex)
            {
                throw new FaultException(ex.Message);
            }
        }

        public bool SuppliesAdd(List<int> supplyDetailIds, int checkinId)
        {
            try
            {
                return _supply.AddSupplies(supplyDetailIds, checkinId);
            }
            catch (Exception ex)
            {
                throw new FaultException(ex.Message);
            }
        }

        public List<SupplyDetail> SupplyDetailsGetByName(string supplyName)
        {
            try
            {
                return _supply.GetSupplyDetails(supplyName, true);
            }
            catch (Exception ex)
            {
                throw new FaultException(ex.Message);
            }
        }

        #endregion
    }


    [ServiceContract]
    public interface IInternalService
    {
        #region CUSTOMER Management

        [OperationContract]
        bool CustomerAdd(string pIdentityNumber, string pCustomerName, string pCustomerPhone, string pCustomerEmail,
                         bool pCustomerSex, out string account);

        [OperationContract]
        bool CustomerModify(int pId, string pIdentityNumber, string pCustomerName, string pCustomerPhone,
                            string pCustomerEmail, bool pCustomerSex);


        [OperationContract]
        List<Customer> CustomersGet(string customerName, string customerEmail, string customerAccount);

        [OperationContract]
        Customer CustomerGet(int customerId);

        [OperationContract]
        Customer CustomerGetByAccount(string account);

        [OperationContract]
        Customer CustomerGetByEmail(string email);

        [OperationContract]
        bool CustomerEmailCheck(string email);

        [OperationContract]
        bool CustomerAccountCheck(string id);

        #endregion

        #region "SEARCH Room for Booking"

        [OperationContract]
        List<vRoomInfo> RoomsSearch(DateTime inDate, DateTime outDate, int roomTypeId, int minPrice, int maxPrice,
                                    bool view, bool bath, bool balcony);

        #endregion

        #region "Booking Management"

        [OperationContract]
        bool BookingAdd(int customerId, List<int> roomId, DateTime checkInDate, DateTime checkOutDate,
                        string employeeAccount, string employeePassword);

        [OperationContract]
        bool BookingRemove(int bookingId);

        [OperationContract]
        List<Booking> BookingsGetByCustomerId(int customerId);

        [OperationContract]
        Booking BookingGet(int bookingId);

        #endregion

        #region "ROOM Management"

        [OperationContract]
        List<RoomType> RoomTypesGet();

        #endregion

        #region "CHECKIN Management"

        [OperationContract]
        bool CheckInRemove(int checkinId);

        [OperationContract]
        CheckIn CheckInGetById(int checkinId);

        [OperationContract]
        List<CheckIn> CheckInsIncome();

        [OperationContract]
        List<vSupplyOrder> SupplyOrdersGet(int checkinId);

        [OperationContract]
        List<CheckIn> CheckInsGetByBookingId(int bookingId);

        [OperationContract]
        List<CheckIn> CheckInsGetByCustomerId(int customerId);

        [OperationContract]
        bool CheckinLock(List<int> checkinIds);

        [OperationContract]
        bool CheckinsAccept(int checkinId, string employeeAccount, string employeePassword, string guestInfo);

        [OperationContract]
        bool CheckinModify(int checkinId, string guestInfo);

        #endregion

        #region "CHECKOUT Management"

        //[OperationContract]
        //List<vBill> BillGetByBooking(int pBookingID);

        [OperationContract]
        List<vBill> BillGetByCheckins(List<int> checkinId);

        //[OperationContract]
        //bool CheckOutByBooking(int bookingId, string employeeAccount, string employeePassword);

        [OperationContract]
        List<vBill> CheckOutByCheckins(List<int> checkinId, string employeeAccount, string employeePassword);

        #endregion

        #region "SUPPLY"

        [OperationContract]
        List<SupplyDetail> SupplyDetailsGet();

        [OperationContract]
        List<Supply> SuppliesGetByCheckinId(int checkinId);

        [OperationContract]
        bool SuppliesAdd(List<int> supplyDetailIds, int checkinId);

        [OperationContract]
        List<SupplyDetail> SupplyDetailsGetByName(string supplyName);

        #endregion
    }
}